Trò chơi Tic-Tac-Toe, game đánh caro full source code
- PickupItemSyncer.cs
- UtilityScripts /
- Photon Unity Networking /
- Assets /
- project /
2 using UnityEngine;
3 using System.Collections;
4 using Hashtable = ExitGames.Client.Photon.Hashtable;
5
6
7 /// <summary>Finds out which PickupItems are not spawned at the moment and send this to new players.</summary>
8 /// <remarks>Attach this component to a single GameObject in the scene, not to all PickupItems.</remarks>
9 [RequireComponent(typeof(PhotonView))]
10 public class PickupItemSyncer : Photon.MonoBehaviour
11 {
12 public bool IsWaitingForPickupInit;
13 private const float TimeDeltaToIgnore = 0.2f;
14
15
16 public void OnPhotonPlayerConnected(PhotonPlayer newPlayer)
17 {
18 if (PhotonNetwork.isMasterClient)
19 {
20 this.SendPickedUpItems(newPlayer);
21 }
22 }
23
24 public void OnJoinedRoom()
25 {
26 Debug.Log("Joined Room. isMasterClient: " + PhotonNetwork.isMasterClient + " id: " + PhotonNetwork.player.ID);
27 // this client joined the room. let's see if there are players and if someone has to inform us about pickups
28 this.IsWaitingForPickupInit = !PhotonNetwork.isMasterClient;
29
30 if (PhotonNetwork.playerList.Length >= 2)
31 {
32 this.Invoke("AskForPickupItemSpawnTimes", 2.0f);
33 }
34 }
35
36
37 public void AskForPickupItemSpawnTimes()
38 {
39 if (this.IsWaitingForPickupInit)
40 {
41 if (PhotonNetwork.playerList.Length < 2)
42 {
43 Debug.Log("Cant ask anyone else for PickupItem spawn times.");
44 this.IsWaitingForPickupInit = false;
45 return;
46 }
47
48
49 // find a another player (than the master, who likely is gone) to ask for the PickupItem spawn times
50 PhotonPlayer nextPlayer = PhotonNetwork.masterClient.GetNext();
51 if (nextPlayer == null || nextPlayer.Equals(PhotonNetwork.player))
52 {
53 nextPlayer = PhotonNetwork.player.GetNext();
54 //Debug.Log("This player is the Master's next. Asking this client's 'next' player: " + ((nextPlayer != null) ? nextPlayer.ToStringFull() : ""));
55 }
56
57 if (nextPlayer != null && !nextPlayer.Equals(PhotonNetwork.player))
58 {
59 this.photonView.RPC("RequestForPickupTimes", nextPlayer);
60
61 // you could restart this invoke and try to find another player after 4 seconds. but after a while it doesnt make a difference anymore
62 //this.Invoke("AskForPickupItemSpawnTimes", 2.0f);
63 }
64 else
65 {
66 Debug.Log("No player left to ask");
67 this.IsWaitingForPickupInit = false;
68 }
69 }
70 }
71
72 [RPC]
73 public void RequestForPickupTimes(PhotonMessageInfo msgInfo)
74 {
75 if (msgInfo.sender == null)
76 {
77 Debug.LogError("Unknown player asked for PickupItems");
78 return;
79 }
80
81 SendPickedUpItems(msgInfo.sender);
82 }
83
84
85 /// <summary>Summarizes all PickupItem ids and spawn times for new players. Calls RPC "PickupItemInit".</summary>
86 /// <param name="targtePlayer">The player to send the pickup times to. It's a targetted RPC.</param>
87 private void SendPickedUpItems(PhotonPlayer targtePlayer)
88 {
89 if (targtePlayer == null)
90 {
91 Debug.LogWarning("Cant send PickupItem spawn times to unknown targetPlayer.");
92 return;
93 }
94
95 double now = PhotonNetwork.time;
96 double soon = now + TimeDeltaToIgnore;
97
98
99 PickupItem[] items = new PickupItem[PickupItem.DisabledPickupItems.Count];
100 PickupItem.DisabledPickupItems.CopyTo(items);
101
102 List<float> valuesToSend = new List<float>(items.Length * 2);
103 for (int i = 0; i < items.Length; i++)
104 {
105 PickupItem pi = items[i];
106 if (pi.SecondsBeforeRespawn <= 0)
107 {
108 valuesToSend.Add(pi.ViewID);
109 valuesToSend.Add((float)0.0f);
110 }
111 else
112 {
113 double timeUntilRespawn = pi.TimeOfRespawn - PhotonNetwork.time;
114 if (pi.TimeOfRespawn > soon)
115 {
116 // the respawn of this item is not "immediately", so we include it in the message "these items are not active" for the new player
117 Debug.Log(pi.ViewID + " respawn: " + pi.TimeOfRespawn + " timeUntilRespawn: " + timeUntilRespawn + " (now: " + PhotonNetwork.time + ")");
118 valuesToSend.Add(pi.ViewID);
119 valuesToSend.Add((float)timeUntilRespawn);
120 }
121 }
122 }
123
124 Debug.Log("Sent count: " + valuesToSend.Count + " now: " + now);
125 this.photonView.RPC("PickupItemInit", targtePlayer, PhotonNetwork.time, valuesToSend.ToArray());
126 }
127
128
129 [RPC]
130 public void PickupItemInit(double timeBase, float[] inactivePickupsAndTimes)
131 {
132 this.IsWaitingForPickupInit = false;
133
134 // if there are no inactive pickups, the sender will send a list of 0 items. this is not a problem...
135 for (int i = 0; i < inactivePickupsAndTimes.Length / 2; i++)
136 {
137 int arrayIndex = i*2;
138 int viewIdOfPickup = (int)inactivePickupsAndTimes[arrayIndex];
139 float timeUntilRespawnBasedOnTimeBase = inactivePickupsAndTimes[arrayIndex + 1];
140
141
142 PhotonView view = PhotonView.Find(viewIdOfPickup);
143 PickupItem pi = view.GetComponent<PickupItem>();
144
145 if (timeUntilRespawnBasedOnTimeBase <= 0)
146 {
147 pi.PickedUp(0.0f);
148 }
149 else
150 {
151 double timeOfRespawn = timeUntilRespawnBasedOnTimeBase + timeBase;
152
153 Debug.Log(view.viewID + " respawn: " + timeOfRespawn + " timeUntilRespawnBasedOnTimeBase:" + timeUntilRespawnBasedOnTimeBase + " SecondsBeforeRespawn: " + pi.SecondsBeforeRespawn);
154 double timeBeforeRespawn = timeOfRespawn - PhotonNetwork.time;
155 if (timeUntilRespawnBasedOnTimeBase <= 0)
156 {
157 timeBeforeRespawn = 0.0f;
158 }
159
160 pi.PickedUp((float) timeBeforeRespawn);
161 }
162 }
163 }
164 }
this client joined the room. let's see if there are players and if someone has to inform us about pickups
find a another player (than the master, who likely is gone) to ask for the PickupItem spawn times
Debug.Log("This player is the Master's next. Asking this client's 'next' player: " + ((nextPlayer != null) ? nextPlayer.ToStringFull() : ""));
you could restart this invoke and try to find another player after 4 seconds. but after a while it doesnt make a difference anymore
this.Invoke("AskForPickupItemSpawnTimes", 2.0f);
The player to send the pickup times to. It's a targetted RPC.
the respawn of this item is not "immediately", so we include it in the message "these items are not active" for the new player
if there are no inactive pickups, the sender will send a list of 0 items. this is not a problem...